#include <BMPackSim.h>
#include <conveyor.h>
#include <ellipseitem.h>
#include <ItemCreator.h>
#include <gui\graphicsview\qgraphicsscene.h>
#include <gui\kernel\qapplication.h>
#include <corelib\kernel\qobjectdefs.h>




namespace PackSim
{

	BMPackSim::BMPackSim(QObject* parent)
	:QObject(parent)
	{
		mGraphicsScene = new QGraphicsScene();
		mGraphicsScene->setSceneRect(0, 0, 600, 600);
		mGraphicsScene->setItemIndexMethod(QGraphicsScene::NoIndex);

		mSimulating = false;

		QObject::connect(&mMainTimer,SIGNAL(timeout()),this,SLOT(onMainTimerTimeOut()) );
		bool test = QObject::connect(this,SIGNAL(invokeUpdateAll(int)),this,SLOT(onInvokeUpdateAll(int)) ,Qt::QueuedConnection);

	}

	BMPackSim::~BMPackSim()
	{

	}



	void BMPackSim::onMainTimerTimeOut()
	{
		foreach(Conveyor* cnv,mConveyorMap)
		{
			cnv->updateCnv(gcDELTA_TIME);
		}
		//emit mainTimerTimeOut();
	}


	void BMPackSim::startSimulation()
	{
		mSimulating = true;
		//QThread::start();
		start();
		//run();
		//mMainTimer.start(gcDELTA_TIME);
	}

	void BMPackSim::stopSimulation()
	{
		mSimulating = false;
		//mMainTimer.stop();
	}


	void BMPackSim::destroyConveyor()
	{

	}




	void BMPackSim::createConveyor(const QString& aCnvName )
	{
		Conveyor* cnv = new Conveyor();
		//cnv->moveToThread(QApplication::instance()->thread());
		mConveyorMap.insert(aCnvName,cnv);
		mGraphicsScene->addItem(cnv);
	}

	Conveyor* BMPackSim::getConveyor(const QString& aCnvName )
	{
		Conveyor* retVal = 0;
		retVal = mConveyorMap.value(aCnvName);
		return retVal;
	}

	EllipseItem* BMPackSim::createEllipseItem( Conveyor *aConveyor )
	{
		EllipseItem *item = new EllipseItem(aConveyor);
		//item->moveToThread(this);
		mGraphicsScene->addItem(item);
		return item;

	}

	void BMPackSim::destroyEllipseItem( EllipseItem *aEllipseItem )
	{
		delete aEllipseItem;
	}


	ItemCreator* BMPackSim::createItemCreator( const QString& aItemCreatorName )
	{
		ItemCreator *itemCreator = new ItemCreator();
		//itemCreator->moveToThread(this);
		mItemCreatorMap.insert(aItemCreatorName,itemCreator);
		mGraphicsScene->addItem(itemCreator);
		return itemCreator;
	}

	void BMPackSim::destroyItemCreator()
	{

	}

	ItemCreator* BMPackSim::getItemCreator( const QString& aItemCreatorName )
	{
		ItemCreator* retVal = 0;
		retVal = mItemCreatorMap.value(aItemCreatorName);
		return retVal;
	}


	QGraphicsScene* BMPackSim::scene()
	{
		return mGraphicsScene;
	}

	QMap<QString, Conveyor*> BMPackSim::conveyorMap() const
	{
		return mConveyorMap;

	}

	QMap<QString, ItemCreator*> BMPackSim::itemCreatorMap() const
	{
		return mItemCreatorMap;
	}

	void BMPackSim::run()
	{
		mSimulationTime.start();
		while (mSimulating)
		{
			int mDeltaTime = mSimulationTime.elapsed();
			mSimulationTime.restart();
			bool test = false;
		
			//test = QMetaObject::invokeMethod(this,"updateAll",Qt::QueuedConnection,Q_ARG(int,mDeltaTime));
			mutex.lock();
			updatedAll = false;
			emit invokeUpdateAll(mDeltaTime);
			
			while(!updatedAll);
			//mWaitContition.wait(&mutex);
			mutex.unlock();
			
		
		}
		
	}

	void BMPackSim::onInvokeUpdateAll( int deltaTime )
	{
		foreach(Conveyor* cnv,mConveyorMap)
		{
			cnv->updateCnv(deltaTime);
		}
		foreach(ItemCreator* iCrt,mItemCreatorMap)
		{
			iCrt->update(deltaTime);
		}
		//mWaitContition.wakeOne();
		updatedAll = true;
	}

}

